home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / docs / ippon / eshot / 7 / eshot.c next >
C/C++ Source or Header  |  2000-07-07  |  6KB  |  274 lines

  1. /* eshot.c */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <math.h>        /* sin,cos を使うために */
  6. #include <sys/iocs.h>
  7. #include "XSP2lib.H"
  8.  
  9. #define PCG_MAX    32        /* パターンデータの個数 */
  10.  
  11.  
  12. static char pcg_alt[PCG_MAX + 1];    /* PCG配置管理テーブル */
  13. static char pcg_dat[PCG_MAX * 128];    /* PCGデータファイル読み込みバッファ */
  14.  
  15. static unsigned short pal_dat[16][15];    /* パレットデータ */
  16.  
  17.  
  18. #define ESHOT_MAX    200    /* 敵弾最大数 */
  19. #define ESHOT_SPEED    0.75    /* 敵弾の速度 */
  20.  
  21.  
  22. /* 敵弾構造体 */
  23. typedef struct _eshot {
  24.     /* 以下の4項目は xsp_set_st() で使うため順不同 */
  25.     signed short x;        /* 敵弾のX座標 */
  26.     signed short y;        /*  〃 Y座標 */
  27.     short pt;        /* スプライトパターンNo. */
  28.     short info;        /* 反転コード・色・優先度を表わすデータ */
  29.  
  30.     unsigned char type;    /*  〃 種類 */
  31.     unsigned char angle;    /* 角度 (0~255) */
  32.     signed int lx, ly;    /* 32bit X,Y 座標 ( l = longword ) */
  33.     signed int vx, vy;    /* 32bit X,Y 速度 ( v = velocity ) */
  34.     struct _eshot *next;    /* 次の構造体へのポインタ */
  35. } ESHOT;
  36.  
  37. ESHOT *eshot_top;        /* 使用中のワークのリスト */
  38. ESHOT *eshot_null_top;        /* 未使用ワークのリスト */
  39. ESHOT eshot[ESHOT_MAX];        /* ワーク */
  40.  
  41. /* EshotAlloc の引き数構造体 */
  42. typedef struct {
  43.     signed short x;        /* 敵弾のX座標 */
  44.     signed short y;        /*  〃 Y座標 */
  45.     unsigned char type;    /*  〃 種類 */
  46.     unsigned char angle;    /* 角度 (0~255) */
  47. } ESHOTA;
  48.  
  49.  
  50. #define EshotAlloc(eshot_x,eshot_y,eshot_type,eshot_angle)    \
  51.             {\
  52.                 ESHOTA eshota, *_eshota = &eshota;\
  53.                 _eshota->x = eshot_x;\
  54.                 _eshota->y = eshot_y;\
  55.                 _eshota->type = eshot_type;\
  56.                 _eshota->angle = eshot_angle;\
  57.                 EshotAllocF (_eshota);\
  58.             }
  59.  
  60.  
  61.  
  62. typedef struct {
  63.     signed int x, y;
  64. } VECTOR;
  65.  
  66. VECTOR xytable[256];        /* sin,cos テーブル */
  67.  
  68.  
  69.  
  70. /* ゲーム開始時に呼ばれる */
  71. void EshotInit (void)
  72. {
  73.     int i;
  74.  
  75.     /* リストをつなげる */
  76.     eshot_top = NULL;
  77.     eshot_null_top = eshot;
  78.     for (i = 0; i < ESHOT_MAX; i++)
  79.         eshot[i].next = &eshot[i + 1];    /* 次を指すようにする */
  80.  
  81.     eshot[ESHOT_MAX - 1].next = NULL;    /* 「一番最後の次」はない */
  82. }
  83.  
  84.  
  85.  
  86. /* 敵弾出現時に呼ばれる */
  87. /* 引き数 : ESHOTA 構造体  */
  88. void EshotAllocF (ESHOTA * a)
  89. {
  90.     ESHOT *p;
  91.  
  92.     if (eshot_null_top == NULL)    /* ワークの空きはあるか? */
  93.         return;
  94.  
  95.     p = eshot_null_top;
  96.     eshot_null_top = p->next;
  97.     p->next = eshot_top;
  98.     eshot_top = p;
  99.  
  100.     p->lx = (a->x - 8) << 16;    /* (8,8) がスプライト座標の中心なので補正 */
  101.     p->ly = (a->y - 8) << 16;
  102.     {
  103.         int a_angle = a->angle;
  104.         p->vx = xytable[a_angle].x;
  105.         p->vy = xytable[a_angle].y;
  106.     }
  107.     p->pt = p->type = a->type;    /* スプライトパターン番号 */
  108.     p->info = 0x033f;    /* 反転コード・色・優先度を表わすデータ */
  109. }
  110.  
  111.  
  112.  
  113. /* 垂直同期ごとに呼ばれる */
  114. void EshotMove (void)
  115. {
  116.     ESHOT *p, *q;
  117.  
  118.     p = eshot_top;        /* 現在注目しているワーク */
  119.     q = NULL;        /* 1つ前のワーク(ワーク削除時に必要) */
  120.  
  121.     while (p != NULL) {
  122.         signed short p_x, p_y;    /* p->x, p->y と同じ */
  123.  
  124.         /* 速度を足して上位ワード(固定整数部)だけ取り出す */
  125.         p_x = p->x = (p->lx += p->vx) >> 16;
  126.         p_y = p->y = (p->ly += p->vy) >> 16;
  127.  
  128.  
  129.         /* 敵弾が画面外に出たか? */
  130.         /* (画面右から出た判定と左から出た判定を1回の比較で行っている) */
  131.         if (((unsigned short) p_x > 256 + 16) || ((unsigned short) p_y > 256 + 16)) {
  132.             /* 画面外に出たので消去 */
  133.             if (q == NULL) {    /* リストの一番最初を削除 */
  134.                 eshot_top = p->next;
  135.                 p->next = eshot_null_top;
  136.                 eshot_null_top = p;
  137.                 q = NULL;
  138.                 p = eshot_top;
  139.             } else {
  140.                 q->next = p->next;
  141.                 p->next = eshot_null_top;
  142.                 eshot_null_top = p;
  143.                 p = q->next;
  144.             }
  145.         } else {
  146.             xsp_set_st (p);
  147.  
  148.             q = p;
  149.             p = p->next;
  150.         }
  151.     }
  152. }
  153.  
  154.  
  155.  
  156. int main (int argc, char *argv[])
  157. {
  158.     FILE *fp;
  159.     int i, j;
  160.     int game_over = 0;
  161.     unsigned char angle = 0;    /* 次に撃つ弾の角度 */
  162.     unsigned char type = 1;    /* 次に撃つ弾の種類 */
  163.     int sprites;        /* スプライトの枚数 */
  164.  
  165.     if (argc != 1) {
  166.         printf (
  167.                    "敵弾テストその7(完璧版) ESHOT.X\n"
  168.                    "        programmed by Mitsuky <FreeSoftware>\n"
  169.                    "\n"
  170.             );
  171.         exit (-1);
  172.     }
  173.     printf ("データテーブルを作成します。\n");
  174.     for (i = 0; i < 256; i++) {
  175.         xytable[i].x = (signed int) (cos (2.0 * M_PI * (long) i / 256.0) * 65536.0 * ESHOT_SPEED);
  176.         xytable[i].y = (signed int) (sin (2.0 * M_PI * (long) i / 256.0) * 65536.0 * ESHOT_SPEED);
  177.     }
  178.  
  179.  
  180.     _iocs_crtmod (10);    /* 256x256ドット グラフィック画面 256色 2画面 */
  181.     _iocs_g_clr_on ();    /* グラフィック画面の初期化 */
  182.     _iocs_sp_init ();    /* スプライトの初期化 */
  183.     _iocs_sp_on ();
  184.  
  185.     /* pcg_dat にパターンデータを読み込む */
  186.     fp = fopen ("ESHOT.SP", "rb");
  187.     fread (pcg_dat, sizeof (char), PCG_MAX * 128, fp);
  188.     fclose (fp);
  189.  
  190.     /* pal_buf に一旦パレットデータを読み込む */
  191.     fp = fopen ("ESHOT.PAL", "rb");
  192.     fread (pal_dat, sizeof (unsigned short), 16 * 15, fp);
  193.     fclose (fp);
  194.     /* パレットデータを定義 */
  195.     /* (1パレットブロック=16色) × (15ブロックぶん) 定義する */
  196.     {
  197.         unsigned short *p = (unsigned short *) pal_dat;
  198.         for (i = 1; i < 15; i++)
  199.             for (j = 0; j < 16; j++)
  200.                 _iocs_spalet (0x80000000 | j, i, *p++);
  201.     }
  202.  
  203.     xsp_on ();
  204.     xsp_mode (3);
  205.     /* パターンデータを定義 */
  206.     xsp_pcgdat_set (pcg_dat, pcg_alt, sizeof (pcg_alt));
  207.  
  208.     /* グラフィック画面に線を引く */
  209.     {
  210.         struct _lineptr lp;
  211.         lp.x1 = 0;
  212.         lp.y1 = 128;
  213.         lp.x2 = 255;
  214.         lp.y2 = 128;
  215.         lp.color = 15;
  216.         lp.linestyle = 0xaaaa;
  217.         _iocs_line (&lp);
  218.         lp.x1 = 128;
  219.         lp.y1 = 0;
  220.         lp.x2 = 128;
  221.         lp.y2 = 255;
  222.         _iocs_line (&lp);
  223.     }
  224.  
  225.     printf ("ジョイスティックの\n"
  226.         " [B] ボタンを押すと弾を撃ちます\n"
  227.         " [A] ボタンを押すと終了します\n");
  228.  
  229.  
  230.     EshotInit ();
  231.  
  232.     do {
  233.         xsp_vsync (0);    /* 垂直同期待ち */
  234.         j = _iocs_joyget (0);    /* ジョイスティック0番 */
  235.  
  236.         /* [A] ボタンが押されたか? */
  237.         if ((j & 0b00100000) == 0)
  238.             game_over = !0;        /* ゲームオーバーに */
  239.  
  240.         /* [B] ボタンが押されたか? */
  241.         if ((j & 0b1000000) == 0) {
  242.             /* 種類 type の敵弾を座標(144,144)、角度 angle で発生 */
  243. #if    0
  244.             /* ここと#else以降は等価(マクロにしただけ) */
  245.             {
  246.                 ESHOTA eshota, *_eshota = &eshota;
  247.                 _eshota->x = 144;
  248.                 _eshota->y = 144;
  249.                 _eshota->type = type;
  250.                 _eshota->angle = angle;
  251.                 EshotAllocF (_eshota);
  252.             }
  253. #else
  254.             EshotAlloc (144, 144, type, angle);
  255. #endif
  256.             angle += 8;    /* 角度を進める */
  257.             type++;    /* 種類を進める(意味無し) */
  258.             if (type > 5)
  259.                 type = 1;
  260.         }
  261.         EshotMove ();
  262.         sprites = xsp_out ();    /* 表示 */
  263.  
  264.         printf ("弾数 = %3d  \n\x0b", sprites);
  265.         /* 0x0b はカーソルを1行上に移動する */
  266.         /* Human68K ユーザーズマニュアルの付録 ASCII 制御コードの欄参照 */
  267.     } while (!game_over);
  268.  
  269.     xsp_off ();
  270.  
  271.     _iocs_crtmod (16);
  272.     return (0);
  273. }
  274.